package com.xcity.game.activity.str;

import java.text.MessageFormat;
import java.util.concurrent.TimeUnit;

import com.xcity.db.entity.Player;
import com.xcity.game.activity.ActivityService;
import com.xcity.game.activity2.ActivityIds;
import com.xcity.game.common.Cause;
import com.xcity.game.common.GameStaticConfig;
import com.xcity.game.common.MessageConst;
import com.xcity.game.common.PlayerPool;
import com.xcity.game.event.GameEvents;
import com.xcity.pomelo.PomeloRoute;
import com.xcity.pomelo.push.msg.ActivityStatePush;
import com.xcity.pomelo.request.StrengthMealRequest;
import com.xcity.pomelo.response.HintResponse;
import com.xcity.pomelo.response.StrengthMealResponse;

import naga.x.App;
import naga.x.event.Event;
import naga.x.event.EventListener;
import naga.x.game.time.DayListener;
import naga.x.game.time.TimeUpdater;
import naga.x.net.Session;
import naga.x.net.annotation.OPHandler;
import naga.x.net.impl.pomelo.annotation.PomeloOP;
import naga.x.service.ServiceException;
import naga.x.util.TimeUtils;

/**
 * 体力奖励（午餐、晚餐）
 * @author yang.li
 *
 */
@OPHandler
public class StrengthMealActivityService extends ActivityService implements DayListener, EventListener {

	protected StrengthMeal lunch, dinner;
	
	protected static final int HOUR_LUNCH = 12, HOUR_DINNER = 18;
	
	@Override
	public void startup() throws ServiceException {
		lunch = new StrengthMeal(StrengthMeal.TYPE_LUNCH);
		dinner = new StrengthMeal(StrengthMeal.TYPE_DINNER);
		dayChanged();
		App.getApp().getEventManager().register(this);
		TimeUpdater.getInstance().addDayListener(this);
	}

	@Override
	public void shutdown() throws ServiceException {
	}

	@Override
	public boolean dayChanged() {
		long t = TimeUtils.getTodayZeroTime();
		lunch.reset(t + TimeUnit.HOURS.toMillis(HOUR_LUNCH));
		dinner.reset(t + TimeUnit.HOURS.toMillis(HOUR_DINNER));
		return true;
	}
	
	@Override
	public int[] getEventTypes() {
		return new int[] { GameEvents.EVENT_PLAYER_LOGIN, GameEvents.EVENT_PLAYER_LOADED, GameEvents.EVENT_PLAYER_LEVEL_UP };
	}

	@Override
	public void handleEvent(Event event) {
		switch (event.getType()) {
			case GameEvents.EVENT_PLAYER_LOGIN:
				playerLogin(event.getParameter());
				break;
			case GameEvents.EVENT_PLAYER_LOADED:
				playerLoaded(event.getParameter());
				break;
			case GameEvents.EVENT_PLAYER_LEVEL_UP:
				playerLevelUp(event.getParameter());
				break;
		}
	}
	
	private void playerLogin(Player player) {
		player.resetStrength(Cause.LOGIN);
	}
	
	private void playerLoaded(Player player) {
		StrengthMeal meal = getMeal();
		byte state = getReceiveState(player, meal);
		if (state == StrengthMeal.CAN_RECEIVE) {
			player.send(new ActivityStatePush(ActivityIds.ACTIVITY_STRENGTH_MEAL, STATE_OPENED));
		}
	}
	
	private void playerLevelUp(Player player) {
		playerLoaded(player);
	}
	
	@PomeloOP(PomeloRoute.GET_STRENGTH_MEAL)
	protected void requestMeal(Session session, StrengthMealRequest req) {
		Player player = session.getClient();
//		if (req.getType() == -1) { // 请求状态
//			byte type = TimeUpdater.getInstance().now() < PlayerUtils.strengthDinnerTime ? PlayerUtils.LUNCH_STRENGTH : PlayerUtils.DINNER_STRENGTH;
//			byte state = PlayerUtils.getTodayStrengthMealState(player, type);
//			session.send(new StrengthMealResponse(req.getSerial(), type, state));
//			return;
//		}
//		if (req.getType() != 0 && req.getType() != 1) {
//			session.send(new HintResponse(req.getSerial(), MessageConst.ILLEGAL_OPERATION));
//			return;
//		}
		StrengthMeal meal = getMeal();
		String error = getStrengthMeal(player, meal);
		if (error != null) {
			session.send(new HintResponse(req.getSerial(), error));
			return;
		}
		session.send(new ActivityStatePush(ActivityIds.ACTIVITY_STRENGTH_MEAL, STATE_CLOSED));
		session.send(new StrengthMealResponse(req.getSerial(), getReceiveState(player, meal)));
	}
	
	/**
	 * 获取当前匹配的meal
	 * @return
	 */
	private StrengthMeal getMeal() {
		return TimeUpdater.getInstance().now() < dinner.getTime() ? lunch : dinner;
	}
	
	public StrengthMeal getLunch() {
		return lunch;
	}
	
	public StrengthMeal getDinner() {
		return dinner;
	}
	
	public static String getStrengthMeal(Player player, StrengthMeal meal) {
		if (meal.getState() == StrengthMeal.STATE_INIT) {
			return meal.type == StrengthMeal.TYPE_LUNCH ? MessageConst.NOT_LUNCH_TIME : MessageConst.NOT_DINNER_TIME;
		}
		if (meal.getState() == StrengthMeal.STATE_CLOSED) {
			return meal.type == StrengthMeal.TYPE_LUNCH ? MessageConst.LUNCH_OVER : MessageConst.DINNER_OVER;
		}
		if (player.getLevel() < GameStaticConfig.strengthMealActivityOpenLvl) {
			return MessageFormat.format(MessageConst.REWARD_LEVEL_LIMIT, GameStaticConfig.strengthMealActivityOpenLvl);
		}
		if (player.getPool().getLongValue(PlayerPool.PROPERTY_STRENGTH_MEAL_TIME) >= meal.getTime()) {
			return MessageConst.REWARD_ALREADY_RECEIVED;
		}
		player.poolSet(PlayerPool.PROPERTY_STRENGTH_MEAL_TIME, TimeUpdater.getInstance().now());
		player.addStrength(GameStaticConfig.mealRewardStr, meal.type == StrengthMeal.TYPE_LUNCH ? Cause.LUNCH : Cause.DINNER);
		player.addVigour(GameStaticConfig.mealRewardVigour, meal.type == StrengthMeal.TYPE_LUNCH ? Cause.LUNCH : Cause.DINNER);
		return null;
	}
	
	public static byte getReceiveState(Player player, StrengthMeal meal) {
		if (player.getLevel() < GameStaticConfig.strengthMealActivityOpenLvl) {
			return StrengthMeal.CAN_NOT_RECEIVE;
		}
		if (player.getPool().getLongValue(PlayerPool.PROPERTY_STRENGTH_MEAL_TIME) >= meal.getTime()) {
			return StrengthMeal.RECEIVED;
		}
		if (meal.getState() == StrengthMeal.STATE_OPENED) {
			return StrengthMeal.CAN_RECEIVE;
		}
		return StrengthMeal.CAN_NOT_RECEIVE;
	}

}
